package indi.kider.server.apabus.service;

import com.alibaba.fastjson.JSON;
import indi.kider.common.constant.*;
import indi.kider.common.model.apabus.*;
import indi.kider.common.model.apartment.Houses;
import indi.kider.common.model.apartment.HousesMsg;
import indi.kider.common.model.bill.TaskRegist;
import indi.kider.common.model.employee.Employee;
import indi.kider.common.model.employee.Tenant;
import indi.kider.common.model.employee.Waiter;
import indi.kider.server.apabus.mapper.*;
import indi.kider.server.apabus.service.related.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pers.vankid.common.constant.DateTime;
import pers.vankid.common.constant.HttpCode;
import pers.vankid.common.model.base.CommonResponse;
import pers.vankid.common.utils.page.PageRequest;
import pers.vankid.common.utils.page.PageResponse;
import pers.vankid.common.utils.page.PageUtil;
import tk.mybatis.mapper.entity.Example;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.List;

@Service
@SuppressWarnings("ALL")
public class ApabusSericeImpl implements ApabusService {

    @Autowired
    private BusMapper busMapper;
    @Autowired
    private RentMapper rentMapper;
    @Autowired
    private ReletMapper reletMapper;
    @Autowired
    private RentOutlineMapper rentOutlineMapper;
    @Autowired
    private RentMonthReportMapper rentMonthReportMapper;
    @Autowired
    private ReservationMapper reservationMapper;

    @Autowired
    private HouseService houseService;
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private TenantService tenantService;
    @Autowired
    private WaiterService waiterService;
    @Autowired
    private BillService billService;
    @Autowired
    private QuitBillService quitBillService;

    @Override
    public boolean hasRent(Long housesId) {
        Rent rent = new Rent();
        rent.setHousesId(housesId);
        rent.setState(1);
        List<Rent> list = rentMapper.select(rent);
        if (null== list || list.isEmpty()){
            return true;
        }
        return false;
    }

    @Override
    @Transactional
    public Rent rentHouses(RentVo rent) throws Exception {
        Long housesId = rent.getHousesId();
        HousesMsg housesMsg = houseService.getHousesMsgById(housesId).getData();
        Integer states = housesMsg.getState();
        if (states > 1) // 非空置都不能出租
            throw new Exception("房屋已出租！");
        if (rent.getRentDate() == null || rent.getExpireDate() == null)
            throw new Exception("必须指定租住时间！");


        Rent query = new Rent();
        query.setTenantTel(rent.getTenantTel());
        query.setState(StatusCons.VALID);
        List<Rent> rentList = rentMapper.select(query);
        if (rentList != null && !rentList.isEmpty())
            throw new Exception("当前租客存在未退租房屋！");
        /*添加用户*/
        Tenant tenant = new Tenant();
        tenant.setCardId(rent.getCardId());
        tenant.setName(rent.getTenantName());
        tenant.setPhone(rent.getTenantTel());
        tenant.setNationality(rent.getNationality());
        tenant.setState(StatusCons.VALID);
        tenant.setProfessional(rent.getProfessional());
        tenant.setFriendsSize(0);

        tenant.setSex(rent.getSex());
        tenant.setFormCompy(rent.getFormCompy());

        tenant.setType(TenantTypeCons.TENANT);
        tenant = tenantService.add(tenant).getData();
        /*绑定关系*/

        Long tenantId = tenant.getId();        //rent.getTenantId();
        String remark = rent.getRemark();
        rent.setTenantName(tenant.getName());
        rent.setTenantTel(tenant.getPhone());
        rent.setBuilding(housesMsg.getBuilding());
        rent.setCommunity(housesMsg.getCommunity());
        rent.setHouseNumb(housesMsg.getHouseNumb());
        rent.setUnit(housesMsg.getUnit());
        rent.setAddress(housesMsg.getAddress());
        rent.setCommunityId(housesMsg.getCommunityId());
        rent.setHousesId(housesId);
        rent.setTenantId(tenantId);
        rent.setGasCost(housesMsg.getGasCost());
        rent.setNetCost(housesMsg.getNetCost());
        rent.setPowerCost(housesMsg.getPowerCost());
        rent.setWaterCost(housesMsg.getWaterCost());
        rent.setPropertyCosts(housesMsg.getPropertyCosts());
        rent.setRemark(remark);
        rent.setState(RentStateCons.VALID);
        rent.setDeposit(housesMsg.getDeposit());
        rent.setPriceSet(housesMsg.getPriceSet());
        rent.setSetLease(housesMsg.getSetLease());
        rentMapper.insert(rent);

        /*出账单注册*/
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate rentDate = LocalDate.parse(DateTime.SHORT_DATE.format(rent.getRentDate()));
        // TODO 当前使用的为本月的最后一天为水电的结算日，后续进行可配置。
        LocalDate wp = rentDate.with(TemporalAdjusters.lastDayOfMonth());
        LocalDate newDate = rentDate.plusMonths(1);
        Integer cycle = rent.getSetLease();
        TaskRegist taskRegist = new TaskRegist();
        taskRegist.setRent(rent);
        taskRegist.setRentalBlanceCycle(cycle);

        /**
         * 只设置水表的日期，其他都安装水表的进行结算
         * */
        taskRegist.setWaterBlanceDate(wp.format(formatter));          // 水费结算日期  自然月
        taskRegist.setPowerBlanceDate(wp.format(formatter));          // 电费结算日期  自然月
        taskRegist.setNetBlanceDate(newDate.format(formatter));       // 网费结算日期
        taskRegist.setEstateBlanceDate(newDate.format(formatter));    // 物业费结算日期

        taskRegist.setInitPowerReading(rent.getInitPowerReading());
        taskRegist.setInitWaterReading(rent.getInitWaterReading());
        if (cycle.equals(SetLeaseCons.QUARTER))
            newDate = rentDate.plusMonths(3);
        if (cycle.equals(SetLeaseCons.HALF_YERA))
            newDate = rentDate.plusMonths(6);
        else if (cycle.equals(SetLeaseCons.YERA))
            newDate = rentDate.plusYears(1);
        taskRegist.setRentalBlanceDate(newDate.format(formatter));
        System.out.print("+++++++++++++++++" + taskRegist.toString());
        CommonResponse commonResponse = billService.regist(taskRegist);
        if (commonResponse.getStatus().equals(HttpCode.ERROR_BAD_REQUEST))
            throw new Exception(commonResponse.getMsg());
        /*修改房屋状态*/
        Houses houses = new Houses();
        houses.setId(housesId);
        houses.setState(HouseStateCons.RENTED); //1,空置 2,已租 3，配置中
        houses.setReleaseState(HouseReserveCons.NO_RESRVE); // 原来已经发布的房源直接变成未发布状态
        houseService.updateHouseState(houses);
        return rent;

    }


    @Override
    @Transactional
    public Rent rentHouseForImport(RentVo rent) throws Exception {
        Long housesId = rent.getHousesId();
        HousesMsg housesMsg = houseService.getHousesMsgById(housesId).getData();
        Integer states = housesMsg.getState();

        Rent query = new Rent();
        query.setTenantTel(rent.getTenantTel());
        query.setState(StatusCons.VALID);
        List<Rent> rentList = rentMapper.select(query);
        String tempTel = rent.getTenantTel()+"_X"+new Date().getTime();
        if (rentList != null && !rentList.isEmpty()){
            query.setTenantTel(tempTel);
        }
        /*添加用户*/
        Tenant tenant = new Tenant();
        tenant.setCardId(rent.getCardId());
        tenant.setName(rent.getTenantName());
        tenant.setPhone(query.getTenantTel());
        tenant.setNationality(rent.getNationality());
        tenant.setState(StatusCons.VALID);
        tenant.setProfessional(rent.getProfessional());
        tenant.setFriendsSize(0);

        tenant.setSex(rent.getSex());
        tenant.setFormCompy(rent.getFormCompy());

        tenant.setType(TenantTypeCons.TENANT);
        tenant.setRemark("公寓初始化导入");
        tenant = tenantService.add(tenant).getData();
        /*绑定关系*/

        Long tenantId = tenant.getId();        //rent.getTenantId();
        String remark = rent.getRemark();
        rent.setTenantName(tenant.getName());
        rent.setTenantTel(tenant.getPhone());
        rent.setBuilding(housesMsg.getBuilding());
        rent.setCommunity(housesMsg.getCommunity());
        rent.setHouseNumb(housesMsg.getHouseNumb());
        rent.setUnit(housesMsg.getUnit());
        rent.setAddress(housesMsg.getAddress());
        rent.setCommunityId(housesMsg.getCommunityId());
        rent.setHousesId(housesId);
        rent.setTenantId(tenantId);
        rent.setGasCost(housesMsg.getGasCost());
        rent.setNetCost(housesMsg.getNetCost());
        rent.setPowerCost(housesMsg.getPowerCost());
        rent.setWaterCost(housesMsg.getWaterCost());
        rent.setPropertyCosts(housesMsg.getPropertyCosts());
        rent.setRemark(remark);
        rent.setState(RentStateCons.VALID);
        rent.setDeposit(housesMsg.getDeposit());
        rent.setPriceSet(housesMsg.getPriceSet());
        rent.setSetLease(housesMsg.getSetLease());
        System.out.println("===========>"+JSON.toJSONString(rent));
        rentMapper.insert(rent);

        /*出账单注册*/
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate rentDate = LocalDate.parse(DateTime.SHORT_DATE.format(rent.getRentDate()));
        // TODO 当前使用的为本月的最后一天为水电的结算日，后续进行可配置。
        LocalDate wp = rentDate.with(TemporalAdjusters.lastDayOfMonth());
        LocalDate newDate = rentDate.plusMonths(1);
        Integer cycle = rent.getSetLease();
        TaskRegist taskRegist = new TaskRegist();
        taskRegist.setRent(rent);
        taskRegist.setRentalBlanceCycle(cycle);

        /**
         * 只设置水表的日期，其他都安装水表的进行结算
         * */
        taskRegist.setWaterBlanceDate(wp.format(formatter));          // 水费结算日期  自然月
        taskRegist.setPowerBlanceDate(wp.format(formatter));          // 电费结算日期  自然月
        taskRegist.setNetBlanceDate(newDate.format(formatter));       // 网费结算日期
        taskRegist.setEstateBlanceDate(newDate.format(formatter));    // 物业费结算日期

        taskRegist.setInitPowerReading(rent.getInitPowerReading());
        taskRegist.setInitWaterReading(rent.getInitWaterReading());
        if (cycle.equals(SetLeaseCons.QUARTER))
            newDate = rentDate.plusMonths(3);
        if (cycle.equals(SetLeaseCons.HALF_YERA))
            newDate = rentDate.plusMonths(6);
        else if (cycle.equals(SetLeaseCons.YERA))
            newDate = rentDate.plusYears(1);
        taskRegist.setRentalBlanceDate(newDate.format(formatter));
        System.out.print("+++++++++++++++++" + taskRegist.toString());
        CommonResponse commonResponse = billService.regist(taskRegist);
        if (commonResponse.getStatus().equals(HttpCode.ERROR_BAD_REQUEST))
            throw new Exception(commonResponse.getMsg());
        /*修改房屋状态*/
        Houses houses = new Houses();
        houses.setId(housesId);
        houses.setState(HouseStateCons.RENTED); //1,空置 2,已租 3，配置中
        houses.setReleaseState(HouseReserveCons.NO_RESRVE); // 原来已经发布的房源直接变成未发布状态
        houseService.updateHouseState(houses);
        return rent;

    }

    @Transactional
    @Override
    public void rentHouses(Long housesId, Long tenantId, Long rentId) throws Exception {
        CommonResponse c = quitBillService.balanceAllBills(rentId);
        if (c.doUpdateSuccess()) {
            Rent rent = new Rent();
            rent.setState(RentStateCons.MOVED);
            rent.setId(rentId);
            rentMapper.updateByPrimaryKeySelective(rent);

            Houses houses = new Houses();
            houses.setId(housesId);
            houses.setState(HouseStateCons.VACANCY); //1,空置 2,已租 3，配置中
            houseService.updateHouseState(houses);
        } else {
            throw new Exception(c.getMsg());
        }
    }

    @Transactional
    @Override
    public int rentHousesToContract(List<Long> housesIds, Long enterpriseId, Long employeeId) {
        //**不考虑批量 ** ,此业务使用频率不高//
        for (Long housesId : housesIds) {
            RentOutline rentOutline = new RentOutline();
            rentOutline.setHousesId(housesId);
            rentOutline.setEnterprise(enterpriseId);
            rentOutline.setEmployeeId(employeeId);
            rentOutline.setState(RentOutlineStateCons.KEEP_LIVING);
            rentOutlineMapper.insert(rentOutline);
        }
        return housesIds.size();
    }

    @Transactional
    @Override
    public int rentHousesToContract(List<Long> housesIds, Long enterpriseId) {

        RentOutline rentOutline = new RentOutline();
        rentOutline.setState(RentOutlineStateCons.VACANCY);

        Example example = new Example(RentOutline.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("housesId", housesIds);
        criteria.andEqualTo("enterpriseId", enterpriseId);

        return rentOutlineMapper.updateByExampleSelective(rentOutline, example);
    }

    @Transactional
    @Override
    public void rentBusSubmit(Integer busType, String busdeis, Long rentId, Long waiterId) {
        Rent rent = rentMapper.selectByPrimaryKey(rentId);
        Bus bus = new Bus();
        bus.setBusType(busType);
        bus.setTenantId(rent.getTenantId());
        bus.setTenantName(rent.getTenantName());
        bus.setTenantTel(rent.getTenantTel());
        bus.setDes(busdeis);
        bus.setCommunity(rent.getCommunity());
        bus.setHouses(rent.getHouseNumb());
        bus.setInsTime(new Date());
        bus.setHousesId(rent.getHousesId());
        bus.setState(BusStateCons.APPLY);
        bus.setDelState(StatusCons.VALID);
        if (waiterId != null) {
            Waiter waiter = waiterService.getWaiterById(waiterId).getData();
            setWaiter(waiter, bus);
        }
        busMapper.insertSelective(bus);
    }


    @Transactional
    @Override
    public int dispatch(Dispatch dispatch) {
        Waiter waiter = waiterService.getWaiterById(dispatch.getWaiterId()).getData();
        Bus bus = new Bus();
        bus.setId(dispatch.getBusId());
        bus.setWaiterdes(dispatch.getWaiterdes());
        setWaiter(waiter, bus);
        return busMapper.updateByPrimaryKeySelective(bus);
    }

    @Transactional
    @Override
    public int dispatch(Long busId, Long waiterId) {
        Waiter waiter = waiterService.getWaiterById(waiterId).getData();
        Bus bus = new Bus();
        bus.setId(busId);
        setWaiter(waiter, bus);
        return busMapper.updateByPrimaryKeySelective(bus);
    }

    private void setWaiter(Waiter waiter, Bus bus) {
        bus.setWaiter(waiter.getId());
        bus.setWaiterName(waiter.getName());
        bus.setWaiterTel(waiter.getPhone());
        bus.setWaiterTime(new Date());
        bus.setState(BusStateCons.ORDER);
    }

    @Transactional
    @Override
    public int dispatch(Long busId, String result) {
        Bus bus = new Bus();
        bus.setId(busId);
        bus.setResult(result);
        bus.setResultTime(new Date());
        return busMapper.updateByPrimaryKeySelective(bus);
    }

    @Override
    public int complete(CompleteBean completeBean) {
        Bus bus = new Bus();
        bus.setId(completeBean.getBusId());
        bus.setResult(completeBean.getResult());
        bus.setResultTime(completeBean.getResultTime());
        bus.setState(BusStateCons.COMPLETE);
        return busMapper.updateByPrimaryKeySelective(bus);
    }

    /**
     * 逻辑删除服务
     *
     * @param busId
     */
    @Override
    @Transactional
    public void delBus(Long busId, Integer delState) {
        Bus bus = new Bus();
        bus.setId(busId);
        bus.setDelState(delState);
        busMapper.updateByPrimaryKeySelective(bus);
    }

    @Transactional
    @Override
    public int busEvsu(Long busId, int evaluation, String evsu) {
        Bus bus = new Bus();
        bus.setId(busId);
        bus.setEvaluation(evaluation);
        bus.setEvsu(evsu);
        bus.setEvsuTime(new Date());
        return busMapper.updateByPrimaryKeySelective(bus);
    }

    @Override
    public PageResponse<List<Bus>> queryBusList(PageRequest<Bus> request) {
        PageUtil.start(request);
        return PageUtil.getPageResponse(busMapper.getBusList(request.getQuery()));
    }

    /**
     * 根据ID获取租房信息
     *
     * @param id
     * @return
     */
    @Override
    public Rent getRentById(Long id) {
        return rentMapper.selectByPrimaryKey(id);
    }

    /**
     * 根据房屋ID获取租房信息
     *
     * @param id
     * @return
     */
    @Override
    public Rent getRentByHouseId(Long id) {
        Rent query = new Rent();
        query.setHousesId(id);
        query.setState(RentStateCons.VALID);
        return rentMapper.selectOne(query);
    }

    @Override
    public HouseCount queryHouseCount(Long loginId) {
        return rentOutlineMapper.queryHouseCount(loginId);
    }

    @Transactional
    @Override
    public RentOutline insertRentOutLine(RentOutline rentOutline) {
        rentOutlineMapper.insertSelective(rentOutline);
        return rentOutline;
    }

    @Transactional
    @Override
    public int updateReport() {
        rentMonthReportMapper.insertReport();
        return 0;
    }

    @Override
    public List<RentMonthReport> getReportByMonth(String month, String phone) {
        List<Employee> employees = employeeService.getEmploeesToLogin(phone).getData();
        Employee employee = employees.get(0);
        Long enterpriseId = employee.getEnterpriseId();
        Example example = new Example(RentMonthReport.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andGreaterThanOrEqualTo("month", month);
        criteria.andEqualTo("enterprise", enterpriseId);
        return rentMonthReportMapper.selectByExample(example);
    }

    @Override
    public RentMonthReport getReportByNow(String phone) {
        List<Employee> employees = employeeService.getEmploeesToLogin(phone).getData();
        Employee employee = employees.get(0);
        Long enterpriseId = employee.getEnterpriseId();
        return rentMonthReportMapper.getReportByNow(Long.valueOf(enterpriseId));
    }

    /**
     * 续租房屋
     *
     * @param relet
     */
    @Override
    @Transactional
    public void reletHouse(Relet relet) throws Exception {
        Rent rent = rentMapper.selectByPrimaryKey(relet.getRentId());
        relet.setOldExpireDate(rent.getExpireDate());
        relet.setOpTime(new Date());
        reletMapper.insert(relet);


        Rent newRent = new Rent();
        newRent.setId(relet.getRentId());
        newRent.setExpireDate(relet.getNewExpireDate());
        rentMapper.updateByPrimaryKeySelective(newRent);

        Houses houses = new Houses();
        houses.setId(rent.getHousesId());
        CommonResponse commonResponse = houseService.modifyHouses(houses);
    }

    @Override
    public void release(Long id, Integer release) {
        Houses houses = new Houses();
        houses.setId(id);
        houses.setReleaseState(release);
        houseService.updateHouseState(houses);
    }
}
